package com.yst.suivi.services.contrats;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;

import javax.ejb.CreateException;
import javax.ejb.EJBException;
import javax.ejb.FinderException;
import javax.ejb.RemoveException;
import javax.ejb.SessionBean;
import javax.naming.NamingException;

import com.yst.suivi.comparator.NameObjectComparator;
import com.yst.suivi.data.activities.ActivityUtil;
import com.yst.suivi.data.contrats.Contrat;
import com.yst.suivi.data.contrats.ContratLocalHome;
import com.yst.suivi.data.contrats.ContratUtil;
import com.yst.suivi.data.project.Project;
import com.yst.suivi.data.project.ProjectUtil;
import com.yst.suivi.services.AbstractSessionBean;
import com.yst.suivi.services.exceptions.BusinessErrorCode;
import com.yst.suivi.services.exceptions.BusinessException;

/**
 * @ejb.bean display-name="ContratService" jndi-name="ContratHomeRemote"
 *           name="ContratView" type="Stateless" view-type="both"
 */
public class ContratServiceBean extends AbstractSessionBean implements SessionBean
{
	/**
	 * @throws CreateException
	 * @ejb.create-method view-type = "both"
	 */
	public void ejbCreate() throws CreateException
	{
		// by default nothing to do
	}

	/**
	 * This method create a new Contrat.
	 * 
	 * @param standard
	 * @return standard updated
	 * @throws CreateException
	 * @ejb.interface-method view-type = "both"
	 * @ejb.transaction type = "Required"
	 */
	public String createContrat(String nom, String code, String contractor, String refCmd, int workload) throws NamingException, CreateException
	{
		checkConstraints(nom, code, contractor, refCmd, "".intern());
		ContratLocalHome home = ContratUtil.getLocalHome();
		Contrat contrat = home.create();
		updateObject(nom, code, contractor, refCmd, workload, contrat);
		return contrat.getId();
	}

	/**
	 * The method checks if all the business constraints are verified.
	 * 
	 * @param login
	 * @param nom
	 * @param prenom
	 */
	private void checkConstraints(String nom, String code, String contractor, String refCmd, String id)
	{
		String[] parameter = { "contrat", "nom" };
		checkEmptyField(nom, parameter);
		checkFieldLength(nom, SIMPlE_FIELD_MAX_LENGTH, "nom");
		checkUnicity(nom, "contrat", "nom", id, "");

		String[] parameterCode = { "contrat", "code" };
		checkEmptyField(code, parameterCode);
		checkFieldLength(code, SIMPlE_FIELD_MAX_LENGTH, "code");

		checkFieldLength(contractor, SIMPlE_FIELD_MAX_LENGTH, "contractor");
		checkFieldLength(refCmd, SIMPlE_FIELD_MAX_LENGTH, "refCmd");
		checkFieldLength(code, SIMPlE_FIELD_MAX_LENGTH, "code");
	}

	/**
	 * This method update a Contrat.
	 * 
	 * @return standard updated
	 * @throws NamingException
	 * @throws FinderException
	 * @ejb.interface-method view-type = "both"
	 * @ejb.transaction type = "Required"
	 */
	public void storeContrat(String id, String nom, String code, String contractor, String refCmd, int workload) throws FinderException, NamingException
	{

		ContratLocalHome home = ContratUtil.getLocalHome();
		Contrat contrat = home.findByPrimaryKey(id);
		checkConstraints(nom, code, contractor, refCmd, id);
		updateObject(nom, code, contractor, refCmd, workload, contrat);
	}

	/**
	 * La methode remplie l'objet EJB avec les valeurs fournies
	 * 
	 * @param annee
	 * @param mois
	 * @param jour
	 * @param tpsPos
	 * @param prj
	 */
	private void updateObject(String nom, String code, String contractor, String refCmd, int workload, Contrat contrat)
	{
		contrat.setNom(nom);
		contrat.setCode(code);
		contrat.setContractor(contractor);
		contrat.setRefCmd(refCmd);
		contrat.setWorkload(new Integer(workload));
	}

	/**
	 * This method delete a Contrat.
	 * 
	 * @param standard
	 * @throws NamingException
	 * @throws RemoveException
	 * @throws EJBException
	 * @throws FinderException
	 * @ejb.interface-method view-type = "both"
	 * @ejb.transaction type = "Required"
	 */
	public void deleteContrat(String id) throws NamingException, EJBException, RemoveException
	{
		ContratLocalHome home = ContratUtil.getLocalHome();
		home.remove(id);
	}

	/**
	 * This method list all the contrat of the system.
	 * 
	 * @ejb.interface-method view-type = "both"
	 * @ejb.transaction type = "Supports"
	 */
	
	public Collection findAllContrats() throws NamingException, FinderException
	{
		ArrayList retour = new ArrayList(ContratUtil.getLocalHome().findAll());
		Collections.sort(retour, NameObjectComparator.comparator);
		return retour;
	}

	/**
	 * The method returns all the contrat of the given project primary key
	 * 
	 * @param prjId
	 * @return
	 * @throws FinderException
	 * @throws NamingException
	 * @ejb.interface-method view-type = "both"
	 */
	
	public Collection findContrat(String prjId) throws FinderException, NamingException
	{
		Project prj = ProjectUtil.getLocalHome().findByPrimaryKey(prjId);
		ArrayList retour = new ArrayList(prj.getContrats());
		Collections.sort(retour, NameObjectComparator.comparator);
		return retour;
	}

	/**
	 * The method returns the contrat identify by the primary key
	 * 
	 * @param contratKey
	 * @return
	 * @throws FinderException
	 * @throws NamingException.
	 * @ejb.interface-method view-type = "both"
	 */
	public Contrat findContratByKey(String contratKey) throws FinderException, NamingException
	{
		return ContratUtil.getLocalHome().findByPrimaryKey(contratKey);
	}

	/**
	 * The method returns all the project belonging to the contrat
	 * 
	 * @param contrat
	 * @return
	 * @throws FinderException
	 * @throws NamingException
	 * @ejb.interface-method view-type="both"
	 */
	public Collection findProjects(Contrat contrat) throws FinderException, NamingException
	{
		return ProjectUtil.getLocalHome().findProjects(contrat);
	}

	/**
	 * The method links the given contrat with all the projects.
	 * 
	 * @param idContrat
	 * @param idProjects
	 * @throws FinderException
	 * @throws NamingException
	 * @ejb.interface-method view-type="both"
	 */
	
	public void linkedContratToProject(String idContrat, String[] idProjects) throws FinderException, NamingException
	{
		ArrayList listProject = new ArrayList();
		for (int i = 0; i < idProjects.length; i++)
		{
			if (!idProjects[i].equals(""))
			{
				listProject.add(ProjectUtil.getLocalHome().findByPrimaryKey(idProjects[i]));
			}
		}
		Contrat contrat = ContratUtil.getLocalHome().findByPrimaryKey(idContrat);
		// check if the contrat is linked with activities on any deleted
		// projects
		Collection temp = contrat.getProject();
		temp.removeAll(listProject);
		StringBuffer buf = new StringBuffer();
		if (temp.size() > 0)
		{
			Iterator it = temp.iterator();
			Project prj;
			while (it.hasNext())
			{
				prj = (Project) it.next();
				if (0 != ActivityUtil.getLocalHome().findByContratAndProject(contrat, prj).size())
				{
					if (buf.length() > 0)
					{
						buf.append(", ");
					}
					buf.append(prj.getNom());
				}
			}
			if (buf.length() > 0)
			{
				// throw an exception, the delete ue shouldn't have open affeced
				// activities
				String[] parameters = { buf.toString() };
				throw new BusinessException(BusinessErrorCode.DELETED_CONTRAT_CANT_HAVE_ACTIVITY, new String[0], parameters);
			}
		}
		contrat.setProject(listProject);
	}
}
